package tms.controler;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

import tms.Cache;
import tms.model.Booking;
import tms.model.Destination;
import tms.model.Flight;
import tms.service.ServiceHandler;
import tms.view.SearchView;

/**
 *  Implements search methods and pass the results to TravelOption and BookingSummary.
 */
public class SearchController implements IController {
    // property
    public static final String[] TICKET_CLASS = {"Economy", "Business"};

    // view handlers
    SearchView view;

    // reference controllers

    public SearchController() {
    }

    /**
     * Binds data when form is successfully loaded.
     */
    public void bindDataToControls() {
        assert (view != null);
        // init items to GoingTo and LeavingFrom ComboBox
//        List<Destination> destinations = Destination.getListDynamic("");
        List<Destination> destinations = ServiceHandler.getListDestination("");
        if (destinations != null) {
            for (Destination d : destinations) {
                view.addLeavingFromItem(d);
                view.addGoingToItem(d);
            }
        }
    }

    /**
     * Validate user's input before searching flights.
     */
    public boolean validateData() {
        if (view.getLeavingFromFlight().getId() == view.getGoingToFlight().getId()) {
            JOptionPane.showMessageDialog(view, "The place where you are leaving is " +
                    "the same as where you are going to!");
            return false;
        }

        Date now = Calendar.getInstance().getTime();
        Date leaveDate = view.getLeaveDate();
        if (leaveDate.before(now)) {
            JOptionPane.showMessageDialog(view, "Leaving date must not be now or the past!");
            return false;
        }
        if (view.isRoundTripSelected()) {
            Date returnDate = view.getReturnDate();
            if (returnDate.before(now)) {
                JOptionPane.showMessageDialog(view, "Return date must not be now or the past!");
                return false;
            }
            if (leaveDate.after(returnDate)) {
                JOptionPane.showMessageDialog(view, "You return before leaving from here?");
                return false;
            }
        }

        return true;
    }

    /**
     * Old method, maybe deprecated.
     * @param leavingFromId
     */
    public void bindGoingToByLeavingFrom(int leavingFromId) {
        Destination arriving;
        for (Flight d : ServiceHandler.getListFlight("Flight.IDDeparting = " + leavingFromId +
                " and Flight.DepartureDate")) {
            arriving = d.getArriving();
            view.addGoingToItem(arriving);
        }
    }

    /**
     * Search available flights with user's input,
     * then display the next view which will be composed of BookingSummary and TravelOption.
     */
    public void searchFlights(boolean isRoundTrip, int leavingFromId, Date leavingFromDate,
            int goingToId, Date goingToDate, String ticketClass) {

        List<Flight> departResult = new ArrayList<Flight>();
        List<Flight> returnResult = new ArrayList<Flight>();
        final Calendar cal = Calendar.getInstance();

        // bind depart table
        cal.setTime(leavingFromDate);
        departResult = ServiceHandler.getListFlight(
                        "IDDeparting = " + leavingFromId +
                        " and IDArriving = " + goingToId +
                        " and DepDay = " + cal.get(Calendar.DAY_OF_MONTH) +
                        " and DepMonth = " + (cal.get(Calendar.MONTH) + 1) +
                        " and DepYear = " + cal.get(Calendar.YEAR)
        );

        if (isRoundTrip) {
            cal.setTime(goingToDate);
            // bind return table
            returnResult = ServiceHandler.getListFlight(
                    "IDDeparting = " + goingToId +
                    " and IDArriving = " + leavingFromId +
                    " and DepDay = " + cal.get(Calendar.DAY_OF_MONTH) +
                    " and DepMonth = " + (cal.get(Calendar.MONTH) + 1) +
                    " and DepYear = " + cal.get(Calendar.YEAR)
            );
        }

        if (departResult.size() > 0) {
            // Get the first items of results and then pass it as params to BookingSummaryController
            Booking departTicket = new Booking();
            departTicket.setFlight(departResult.get(0));
            departTicket.setTicketClass(ticketClass);
            if (Cache.currentUser != null)
            	departTicket.setIdBookingAccount(Cache.currentUser.getId());
            Booking returnTicket = null;
            if (isRoundTrip && returnResult.size() > 0) {
                returnTicket = new Booking();
                returnTicket.setFlight(returnResult.get(0));
                returnTicket.setTicketClass(ticketClass);
                if (Cache.currentUser != null)
                	returnTicket.setIdBookingAccount(Cache.currentUser.getId());
            }

            // create new BookingSummary view and bind it the data
            SummaryController bsc = new SummaryController(departTicket, returnTicket);
            bsc.createView();
            bsc.bindSummaryInfo(departTicket, returnTicket);

            // create new TravelOption view and bind it the data
            TravelOptionController toc = new TravelOptionController(bsc);
            toc.createView();
            toc.bindSearchResults(departResult, returnResult);

            // change to the next view - which is TravelOptionPanel
            BaseController.getInstance().changeToPanel((JPanel) toc.getView());
        } else {
            JOptionPane.showMessageDialog(view, "There is no found result matching your input!");
        }

    }

    public void createView() {
        view = new SearchView(this);
        bindDataToControls();
        view.setLeaveDate(view.getLeaveDate());
        view.setReturnDate(view.getReturnDate());
    }

    public JPanel getView() {
        if (view == null) {
            createView();
        }
        return view;
    }
}
